import uvicorn
"""
FastAPI应用主文件
提供RPA任务管理的REST API接口
"""
from fastapi import FastAPI, HTTPException, BackgroundTasks
import asyncio
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
from typing import Dict, Any, Optional, List
from datetime import datetime
import uvicorn

from services.task_manager import get_task_manager
from core.utils.logger_manager import LoggerManager


# 创建FastAPI应用
app = FastAPI(
    title="RPA任务管理API",
    description="管理Facebook和LinkedIn平台的RPA自动化任务",
    version="1.0.0"
)

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 获取日志记录器
logger = LoggerManager.get_logger("fastapi_app")


# Pydantic模型定义
class TaskCreateRequest(BaseModel):
    """创建任务请求模型"""
   
    facebook_params: Optional[Dict[str, Any]] = Field(None, description="Facebook任务参数")
    linkedin_params: Optional[Dict[str, Any]] = Field(None, description="LinkedIn任务参数")


class TaskResponse(BaseModel):
    """任务响应模型"""
    task_id: str = Field(..., description="任务ID")
    topic: str = Field(..., description="任务话题")
    status: str = Field(..., description="任务状态")
    created_at: datetime = Field(..., description="创建时间")
    updated_at: datetime = Field(..., description="更新时间")
    results: Optional[Dict[str, Any]] = Field(None, description="任务结果")


class TaskStatusUpdateRequest(BaseModel):
    """任务状态更新请求模型"""
    status: str = Field(..., description="新状态")
    results: Optional[Dict[str, Any]] = Field(None, description="任务结果")


# API路由
@app.get("/")
async def root():
    """根路径"""
    return {"message": "RPA任务管理API服务正在运行"}


@app.get("/health")
async def health_check():
    """健康检查"""
    return {"status": "healthy", "timestamp": datetime.utcnow().isoformat()}


@app.post("/tasks", response_model=Dict[str, str])
async def create_task(request: TaskCreateRequest, background_tasks: BackgroundTasks):
    """创建新任务"""
    try:
        logger.info(f"收到创建任务请求: {request.facebook_params} {request.linkedin_params}")
        
        # 验证参数
        if not request.facebook_params and not request.linkedin_params:
            raise HTTPException(status_code=400, detail="至少需要指定一个平台的参数")
        
        # 获取任务管理器
        task_manager = get_task_manager()
        
        # 创建任务
        task_id = await task_manager.create_task(
            facebook_params=request.facebook_params,
            linkedin_params=request.linkedin_params,
        )
        
        # 在事件循环中启动任务，避免在无事件循环的后台线程中运行异步函数
        task_manager.start_task(task_id)
        
        logger.info(f"任务创建成功: {task_id}")
        return {"task_id": task_id, "message": "任务创建成功"}
        
    except Exception as e:
        logger.error(f"创建任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"创建任务失败: {str(e)}")


@app.get("/tasks/{task_id}", response_model=TaskResponse)
async def get_task(task_id: str):
    """获取任务信息"""
    try:
        logger.info(f"获取任务信息: {task_id}")
        
        task_manager = get_task_manager()
        task_info = await task_manager.get_task_info(task_id)
        
        if not task_info:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        return TaskResponse(
            task_id=task_info["task_id"],
            topic=task_info["topic"],
            status=task_info["status"],
            created_at=task_info["created_at"],
            updated_at=task_info["updated_at"],
            results=task_info.get("results")
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取任务信息失败: {task_id}, 错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取任务信息失败: {str(e)}")


@app.put("/tasks/{task_id}/status")
async def update_task_status(task_id: str, request: TaskStatusUpdateRequest):
    """更新任务状态"""
    try:
        logger.info(f"更新任务状态: {task_id}, 新状态: {request.status}")
        
        task_manager = get_task_manager()
        
        # 检查任务是否存在
        task_info = await task_manager.get_task_info(task_id)
        if not task_info:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        # 更新任务状态
        await task_manager.update_task_status(task_id, request.status, request.results)
        
        logger.info(f"任务状态更新成功: {task_id}")
        return {"message": "任务状态更新成功"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新任务状态失败: {task_id}, 错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"更新任务状态失败: {str(e)}")


@app.delete("/tasks/{task_id}")
async def cancel_task(task_id: str):
    """取消任务"""
    try:
        logger.info(f"取消任务: {task_id}")
        
        task_manager = get_task_manager()
        
        # 检查任务是否存在
        task_info = await task_manager.get_task_info(task_id)
        if not task_info:
            raise HTTPException(status_code=404, detail="任务不存在")
        
        # 取消任务
        success = await task_manager.cancel_task(task_id)
        if not success:
            raise HTTPException(status_code=400, detail="任务无法取消")
        
        logger.info(f"任务取消成功: {task_id}")
        return {"message": "任务取消成功"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"取消任务失败: {task_id}, 错误: {str(e)}")
        raise HTTPException(status_code=500, detail=f"取消任务失败: {str(e)}")


@app.get("/tasks", response_model=List[TaskResponse])
async def get_tasks(limit: int = 50, status: Optional[str] = None):
    """获取任务列表"""
    try:
        logger.info(f"获取任务列表: limit={limit}, status={status}")
        
        task_manager = get_task_manager()
        
        if status:
            # 获取指定状态的任务
            tasks = await task_manager.get_recent_tasks(limit)
            filtered_tasks = [task for task in tasks if task["status"] == status]
        else:
            # 获取所有任务
            filtered_tasks = await task_manager.get_recent_tasks(limit)
        
        return [
            TaskResponse(
                task_id=task["task_id"],
                topic=task["topic"],
                status=task["status"],
                created_at=task["created_at"],
                updated_at=task["updated_at"],
                results=task.get("results")
            )
            for task in filtered_tasks
        ]
        
    except Exception as e:
        logger.error(f"获取任务列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取任务列表失败: {str(e)}")


@app.get("/tasks/active", response_model=List[TaskResponse])
async def get_active_tasks():
    """获取活跃任务列表"""
    try:
        logger.info("获取活跃任务列表")
        
        task_manager = get_task_manager()
        active_tasks = await task_manager.get_active_tasks()
        
        return [
            TaskResponse(
                task_id=task["task_id"],
                topic=task.get("topic", ""),
                status=task["status"],
                created_at=task["created_at"],
                updated_at=task["updated_at"],
                results=task.get("results")
            )
            for task in active_tasks
        ]
        
    except Exception as e:
        logger.error(f"获取活跃任务列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取活跃任务列表失败: {str(e)}")


@app.post("/tasks/cleanup")
async def cleanup_expired_tasks():
    """清理过期任务"""
    try:
        logger.info("开始清理过期任务")
        
        task_manager = get_task_manager()
        await task_manager.cleanup_expired_tasks()
        
        logger.info("过期任务清理完成")
        return {"message": "过期任务清理完成"}
        
    except Exception as e:
        logger.error(f"清理过期任务失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"清理过期任务失败: {str(e)}")


# 启动事件
@app.on_event("startup")
async def startup_event():
    """应用启动事件"""
    logger.info("RPA任务管理API服务启动")


@app.on_event("shutdown")
async def shutdown_event():
    """应用关闭事件"""
    logger.info("RPA任务管理API服务关闭")
    
    # 清理所有活跃任务
    try:
        task_manager = get_task_manager()
        active_tasks = await task_manager.get_active_tasks()
        for task in active_tasks:
            await task_manager.cancel_task(task["task_id"])
        logger.info("所有活跃任务已清理")
    except Exception as e:
        logger.error(f"清理活跃任务失败: {str(e)}")



if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        log_level="info"
    )
